package im.composer.audioservers.rmi.comporessed;

import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

import org.jaudiolibs.audioservers.AudioClient;
import org.jaudiolibs.audioservers.AudioConfiguration;
import org.jaudiolibs.audioservers.AudioServer;

public class GzipRmiAudioServer implements AudioServer {

	private final GZIPAudioTerminal terminal;
	private boolean active = false;
	private String host = null;
	private int port;
	private String name;
	private final Object lock = new Object();

	public GzipRmiAudioServer(AudioClient client, String host, int port, String name) throws RemoteException {
		terminal = new GZIPAudioTerminal(client);
		this.host = host;
		this.port = port;
		this.name = name;
	}

	@Override
	public void run() throws Exception {
		initialise();
		runImpl();
	}

	private void initialise() throws Exception {
		try {
			bind();
			active = true;
		} catch (Exception e) {
			active = false;
			throw e;
		}
	}

	private void runImpl() throws InterruptedException {
		synchronized (lock) {
			while (isActive()) {
				lock.wait();
			}
		}
	}

	public void bind() throws AccessException, RemoteException {
		try {
			LocateRegistry.createRegistry(port);
		} catch (Exception e) {
		}
		LocateRegistry.getRegistry(host, port).rebind(name, terminal);
	}

	public void unbind() throws AccessException, RemoteException, NotBoundException {
		LocateRegistry.getRegistry(host, port).unbind(name);
	}

	@Override
	public AudioConfiguration getAudioContext() {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean isActive() {
		return active;
	}

	@Override
	public void shutdown() {
		active = false;
		lock.notifyAll();
		try {
			unbind();
		} catch (RemoteException | NotBoundException e) {
		}
	}

}
